/******************************************************************
 * 作者：sipeiliu
 * 邮箱：sipeiliu@163.com
 * 描述：安全模块，检测系统状态
 * 日期：2023.4.18
 ******************************************************************/
#include "/opt/sighter/inc/secure.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

/*记录系统信息*/
void sysinfo(void)
{
    int fd_version;       // 系统版本文件描述符
    int fd_cpuinfo;       // cpu信息文件描述符
    int fd_sys;           // 系统信息文件描述符
    int ret;              // 返回值
    char buf[1024] = {0}; // 字符数组

    /*打开系统信息文件*/
    fd_sys = open("/opt/sighter/docs/sysinfo.txt",
                  O_RDWR | O_CREAT,
                  S_IRWXU | S_IRWXG | S_IRWXO);
    if (fd_sys == -1)
    {
        perror("open error");
    }
    /*清空系统信息文件*/
    //fd = open("./test_file", O_WRONLY|O_TRUNC);
    ret = ftruncate(fd_sys, 0);
    if (ret == -1)
    {
        perror("ftruncate error");
    }
    /*写入系统版本信息*/
    fd_version = open("/proc/version", O_RDONLY);
    ret = read(fd_version, buf, sizeof(buf));
    write(fd_sys, "linux verison\n", 14);
    ret = write(fd_sys, buf, ret);
    if (ret == -1)
    {
        perror("write error");
    }
    /*写入cpu信息*/
    fd_cpuinfo = open("/proc/cpuinfo", O_RDONLY);
    ret = read(fd_cpuinfo, buf, sizeof(buf));
    write(fd_sys, "\n\ncpuinfo\n", 10);
    ret = write(fd_sys, buf, ret);
    if (ret == -1)
    {
        perror("write error");
    }
    /*关闭文件*/
    close(fd_version);
    close(fd_cpuinfo);
    close(fd_sys);
}

/*监测系统温度*/
void monitor_temp(void)
{
    int ret;         // 返回值
    int fd_cpu;      // cpu温度文件描述符
    int fd_gpu;      // gpu温度文件描述符
    int fd_led;      // led文件描述符
    char buf_cpu[6]; // cpu温度缓存，字符型
    char buf_gpu[6]; // gpu温度缓存，字符型
    int int_cpu;     // cpu温度缓存，整型
    int int_gpu;     // gpu温度缓存，整型

    // 读取cpu温度
    fd_cpu = open("/sys/class/thermal/thermal_zone0/temp", O_RDONLY); // 打开
    if (fd_cpu == -1)
    {
        perror("cpu sensor error");
    }
    ret = read(fd_cpu, buf_cpu, sizeof(buf_cpu));
    if (ret == -1)
    {
        perror("cpu read error");
    }
    int_cpu = atoi(buf_cpu); // 字符转整型

    // 读取gpu温度
    fd_gpu = open("/sys/class/thermal/thermal_zone1/temp", O_RDONLY);
    if (fd_cpu == -1)
    {
        perror("gpu sensor error");
    }
    ret = read(fd_gpu, buf_gpu, sizeof(buf_gpu));
    if (ret == -1)
    {
        perror("gpu read error");
    }
    int_gpu = atoi(buf_cpu); // 字符转整型

    // cpu达到85度报警或gpu达到90度,闪烁红灯
    fd_led = open("/sys/class/leds/red-led/trigger", O_WRONLY);
    if (fd_led == -1)
    {
        perror("led open error");
    }
    if (int_cpu > 85000 || int_gpu > 90000)
    {
        char buf_led[10] = "heartbeat"; // 闪烁
        ret = write(fd_led, buf_led, sizeof(buf_led));
        if (ret == -1)
        {
            perror("led write error");
        }
    }
    else
    {
        char buf_led[10] = "none"; // 熄灭
        ret = write(fd_led, buf_led, sizeof(buf_led));
        if (ret == -1)
        {
            perror("led write error");
        }
    }

    /*释放文件描述符*/
    close(fd_cpu);
    close(fd_gpu);
    close(fd_led);
}

/*中断符处理函数*/
static void sig_handler(int sig)
{
    /*杀死自己*/
    int ret;
    ret = raise(SIGKILL);
    if(ret == -1)
    {
        printf("raise error\n");
    }   
}

/*安全监测*/
void * thread_secure(void *arg)
{
    sysinfo(); // 获取系统信息
    /*中断符crtl+c处理*/
    sig_t ret = NULL;
    ret = signal(SIGINT, (sig_t)sig_handler);
    if(ret == SIG_ERR)
    {
        perror("signal error");
        exit(-1);
    }
    while (1)
    {
        monitor_temp(); // 监测系统温度
        sleep(10);      // 间隔10秒
    }
}

// void main(void)
// {
//     thread_secure(NULL);
// }